/**
 * 数据库交互模型基类
 * */
import { SelectQueryBuilder } from "typeorm";

export class BaseDao {
  /**
   * 将条件应用到查询构建器 = 匹配
   * @param {SelectQueryBuilder<Entities>} queryBuilder - 查询构建器
   * @param {Array<string>} conditions - 匹配sql数组
   * @param {Array<string|any>} parameters - sql数组中的变量值集合
   * @param {JoinKey} joinKey - 连接符，默认AND，可选OR
   * @return {SelectQueryBuilder<Entities>} 返回一个新的queryBuilder用来构建下一级查询
   * */
  public static applyConditions(queryBuilder: SelectQueryBuilder<Entities>, conditions: string[], parameters: Record<string, any>, joinKey: JoinKey = "AND"): SelectQueryBuilder<Entities> {
    if (conditions.length > 0) queryBuilder.andWhere(conditions.join(` ${joinKey} `), parameters);
    return queryBuilder;
  }

  /**
   * 应用排序 sort 排序
   * @param {SelectQueryBuilder<Entities>} queryBuilder - 查询构建器
   * @param {Array<[string,"ASC"|"DESC]>} sortData - 排序二维数组，每一维都是一组排序，如：[["id","ASC"],["sort","DESC"]]
   * @return {SelectQueryBuilder<Entities>} 返回一个新的queryBuilder用来构建下一级查询
   * */
  public static applySorting(queryBuilder: SelectQueryBuilder<Entities>, sortData: Array<[sortBy: string, sortOrder: "ASC" | "DESC"]>): SelectQueryBuilder<Entities> {
    if (sortData.length > 0) {
      for (const sort of sortData) {
        queryBuilder.addOrderBy(sort[0], sort[1]);
      }
    }
    return queryBuilder;
  }

  /**
   * 应用关联
   * @param {SelectQueryBuilder<Entities>} queryBuilder - 查询构建器
   * @param {string} relations - 关联表实体属性，如：article.cate
   * @param {string} alias - 关联表别名，如：cate
   * @param {string} condition - 关联关系数组，如："article.cate_id = cate.id"
   * @return {SelectQueryBuilder<Entities>} 返回一个新的queryBuilder用来构建下一级查询
   * */
  public static applyRelations(queryBuilder: SelectQueryBuilder<Entities>, relations: string, alias: string, condition: string): SelectQueryBuilder<Entities> {
    if (relations && relations.length > 0) queryBuilder.leftJoinAndSelect(relations, alias, condition);
    return queryBuilder;
  }

  /**
   * 应用分页
   * @param {SelectQueryBuilder<Entities>} queryBuilder - 查询构建器
   * @param {Page} paginationDto - 分页参数
   * @return {SelectQueryBuilder<Entities>} 返回一个新的queryBuilder用来构建下一级查询
   * */
  public static applyPagination(queryBuilder: SelectQueryBuilder<Entities>, paginationDto: Page): SelectQueryBuilder<Entities> {
    const { limit, offset } = paginationDto;
    queryBuilder.skip(offset).take(limit);
    return queryBuilder;
  }

  /**
   * 应用返回字段
   * @param {SelectQueryBuilder<Entities>} queryBuilder - 查询构建器
   * @param {Array<string>} selectFields - 返回字段
   * @return {SelectQueryBuilder<Entities>} 返回一个新的queryBuilder用来构建下一级查询
   * */
  public static applySelect(queryBuilder: SelectQueryBuilder<Entities>, selectFields: string[]): SelectQueryBuilder<Entities> {
    queryBuilder.select(selectFields);
    return queryBuilder;
  }
}

// 支持的实体
export type Entities = any;

export type JoinKey = "AND" | "OR";

export interface Page {
  limit: number;
  offset: number;
}
